`timescale 1ns/1ps
module	tb_top;
	
reg	clk_in,clk_125k,rst_n;
reg test_mode;
reg  [7:0] mod;//mod 1表示128位的，mod0表示测试64位的
reg [1:0] error;
reg [7:0] err_ch64,err_ch128;
wire	txd_ul,	rxd_ul;	
wire	[7:0] manc;
wire	n_sram_ce,	n_sram_lb,	n_sram_oe,	n_sram_ub,	n_sram_we;
wire	[15:0]	sram_dq;
wire	[17:0] sram_ctrl_addr;
wire    [7:0] oe_8ch;

wire manc0,manc1,manc2,manc3,manc4,manc5,manc6,manc7;
wire mod7,mod6,mod5,mod4,mod3,mod2,mod1,mod0;
wire [7:0] jud_err;
 
assign  manc = {manc7,manc6,manc5,manc4,manc3,manc2,manc1,manc0};
assign  {mod7,mod6,mod5,mod4,mod3,mod2,mod1,mod0} = mod  ;
assign  {clk_125k7,clk_125k6,clk_125k5,clk_125k4,
         clk_125k3,clk_125k2,clk_125k1,clk_125k0} = {clk_125k,clk_125k,clk_125k,clk_125k,
                                                     clk_125k,clk_125k,clk_125k,clk_125k} & oe_8ch;
event start_recv,
	  recv_over;
pc			pc_ins(	//input
				.clk(clk_in),
				.nrst(rst_n),
				.rxd(txd_ul/*fpga's transmit*/),//rxd is PC receive 
				//output
				.txd(rxd_ul/*Fpga's receive*/),
				.jud_err(jud_err)//pc judge data
				);
				

test_top		test_top_ins(	//input
					.clk_in(clk_in),
					.rst_n_top(rst_n),
					.rxd_ul(rxd_ul),
					.man_i(manc),
                    .test_mode(test_mode),
					//output
					.txd_ul(txd_ul),
					.sram_ctrl_addr(sram_ctrl_addr),
					.n_sram_we(n_sram_we),
					.n_sram_ce(n_sram_ce),
					.n_sram_oe(n_sram_oe),
					.n_sram_lb(n_sram_lb),
					.n_sram_ub(n_sram_ub),
                    //.oe_8ch(oe_8ch),
                    
					//inout
					.sram_dq(sram_dq)
					);
					
sram_beh		sram_beh_ins(//input
				.clk_50M(clk_in),
				.n_rst(rst_n),
				.n_sram_we(n_sram_we),
				.n_sram_oe(n_sram_oe),
				.n_sram_ce(n_sram_ce),
				.n_sram_lb(n_sram_lb),
				.n_sram_ub(n_sram_ub),
				.sram_addr(sram_ctrl_addr),
				//inout
				.sram_dq(sram_dq)
			);
	
card_4200 card_ins0(//input
				.clk(clk_125k0),
				.mod(mod0),
				.error(error),
				//output
				.manc(manc0),
				.ch(3'd0)
				);
card_4200 card_ins1(//input
				.clk(clk_125k1),
				.mod(mod1),
				.error(error),
				//output
				.manc(manc1),
				.ch(3'd1)
				);
card_4200 card_ins2(//input
				.clk(clk_125k2),
				.mod(mod2),
				.error(error),
				//output
				.manc(manc2),
				.ch(3'd2)
				);	
card_4200 card_ins3(//input
				.clk(clk_125k3),
				.mod(mod3),
				.error(error),
				//output
				.manc(manc3),
				.ch(3'd3)
				);
card_4200 card_ins4(//input
				.clk(clk_125k4),
				.mod(mod4),
				.error(error),
				//output
				.manc(manc4),
				.ch(3'd4)
				);
card_4200 card_ins5(//input
				.clk(clk_125k5),
				.mod(mod5),
				.error(error),
				//output
				.manc(manc5),
				.ch(3'd5)
				);
card_4200 card_ins6(//input
				.clk(clk_125k6),
				.mod(mod6),
				.error(error),
				//output
				.manc(manc6),
				.ch(3'd6)
				);
card_4200 card_ins7(//input
				.clk(clk_125k7),
				.mod(mod7),
				.error(error),
				//output
				.manc(manc7),
				.ch(3'd7)
);
//initial begin
//	force man_o[2]=0;
//end

/********************clk********************************/
initial
begin
	clk_in = 0;
	forever
		#20 clk_in = ~clk_in;
end
initial
begin
	clk_125k = 0;
	forever
		#4000 clk_125k = ~clk_125k;
end

task sys_init;
begin
	rst_n = 0;
	repeat(200)@(posedge clk_in);
	mod  = 8'd0;
	error = 2'b00; 
	rst_n = 1;
    test_mode = 0;//0是4通路测试，1是8路测试
end
endtask

task check_once;
input [7:0]err;
begin
	forever @(posedge clk_in)
		begin
			if(jud_err[0] != err[0])
				$display("[ERROR:] @%t ch0 Compare faild the expect is %b but the act is %b", $time, err[0],jud_err[0]);
			else
				$display("[NOTE:] @%t  ch0 compare sucess", $time);
			if(jud_err[1] != err[1])
				$display("[ERROR:] @%t ch1 Compare faild the expect is %b but the act is %b", $time, err[1],jud_err[1]);
			else
				$display("[NOTE:] @%t  ch1 compare sucess", $time);
			if(jud_err[2] != err[2])
				$display("[ERROR:] @%t ch2 Compare faild the expect is %b but the act is %b", $time, err[2],jud_err[2]);
			else
				$display("[NOTE:] @%t  ch2 compare sucess", $time);
			if(jud_err[3] != err[3])
				$display("[ERROR:] @%t ch3 Compare faild the expect is %b but the act is %b", $time, err[3],jud_err[3]);
			else
				$display("[NOTE:] @%t  ch3 compare sucess", $time);
			if(jud_err[4] != err[4])
				$display("[ERROR:] @%t ch4 Compare faild the expect is %b but the act is %b", $time, err[4],jud_err[4]);
			else
				$display("[NOTE:] @%t  ch4 compare sucess", $time);
			if(jud_err[5] != err[5])
				$display("[ERROR:] @%t ch5 Compare faild the expect is %b but the act is %b", $time, err[5],jud_err[5]);
			else
				$display("[NOTE:] @%t  ch5 compare sucess", $time);
			if(jud_err[6] != err[6])
				$display("[ERROR:] @%t ch6 Compare faild the expect is %b but the act is %b", $time, err[6],jud_err[6]);
			else
				$display("[NOTE:] @%t  ch6 compare sucess", $time);
			if(jud_err[7] != err[7])
				$display("[ERROR:] @%t ch7 Compare faild the expect is %b but the act is %b", $time, err[7],jud_err[7]);
			else
				$display("[NOTE:] @%t  ch7 compare sucess", $time);
			disable check_once;
		end
end
endtask

/******************driver**********************************/
initial
begin: drv
/**************************************************1*/
	sys_init;
	$display("[Note:] @%t testcase is begin", $time);
	pc_ins.pc_init;
	$display("[Note:] @%t pc_init is done", $time);
	pc_ins.recv_init;
	$display("[Note:] @%t recv_init is done", $time);
	pc_ins.pc_script;
  	$display("[Note:] @%t script done", $time); 
	
	
	 /***********************************************1*/
	pc_ins.pc_testbegin;
	$display("[Note:] @%t 1th 64bits mode testcase is start ", $time); 
	@(posedge clk_in)
	begin
		mod <= 8'h00;
		error <= 2'b00;
	end
	->start_recv;
	@(recv_over);
	
	// /*************************************************2*/
	// pc_ins.pc_testbegin;
	// $display("[Note:] @%t 2th 64bits trans error mode testcase is start ", $time);
	// @(posedge clk_in)		
	// begin
		// mod <= 8'h00;
		// error <= 2'b10;
	// end
	// ->start_recv;
	// @(recv_over);
	
	// /*************************************************3*/
	// pc_ins.pc_testbegin;
	// $display("[Note:] @%t 3th 64bits data error mode testcase is start ", $time);
	// @(posedge clk_in)		
		// begin
			// mod <= 8'h00;
			// error <= 2'b01;
		// end
	// ->start_recv;
	// @(recv_over);
	
	/************************************************4*/
	pc_ins.pc_testbegin;
	$display("[Note:] @%t 4th 128bits mode testcase is start ", $time);
	@(posedge clk_in)
	begin
		mod <= 8'hff;
		error <= 2'b00;
	end
	->start_recv;
	@(recv_over);
	
	/***********************************************5*/
	pc_ins.pc_testbegin;
	$display("[Note:] @%t 5th 128bits trans error mode testcase is start ", $time);
	@(posedge clk_in)		
	begin
		mod <= 8'hff;
		error <= 2'b10;
	end
	->start_recv;
	@(recv_over);
	
	
	/********************************************6*/
	pc_ins.pc_testbegin;
	$display("[Note:] @%t 6th 128bits data error mode testcase is start ", $time);
	@(posedge clk_in)		
	begin
		mod <= 8'hff;
		error <= 2'b01;
	end
	->start_recv;
	@(recv_over);
	
	
	
	// /****************************************7*/
	
	// $display("[Note:] @%t 7th 64bits middle in filed mode testcase is start ", $time);
	// @(posedge clk_in)		
	// begin
		// mod <= 8'h00;
		// error <= 2'b00;
	// end
	// repeat(100)@(posedge clk_in);
	// pc_ins.pc_testbegin;
	// ->start_recv;
	// @(recv_over);
	
	/************************************************8*/
	
	$display("[Note:] @%t 8th 128bits middle in filed mode testcase is start ", $time);	
	begin
		mod <= 8'hff;
		error <= 2'b00;
	end
	repeat(100)@(posedge clk_in);	
	pc_ins.pc_testbegin;
	->start_recv;
	@(recv_over);
	
	
     // /****************************************9*/

	// $display("[Note:] @%t 9th 64bits random error mode testcase is start ", $time);
	// @(posedge clk_in)
	// err_ch64 = {$random} % 256;
	// if(err_ch64[7])
		// force manc7 = 0;
	// if(err_ch64[6])
		// force manc6 = 0;
	// if(err_ch64[5])
		// force manc5 = 0;
	// if(err_ch64[4])
		// force manc4 = 0;
	// if(err_ch64[3])
		// force manc3 = 0;
	// if(err_ch64[2])
		// force manc2 = 0;
	// if(err_ch64[1])
		// force manc1 = 0;
	// if(err_ch64[0])
		// force manc0 = 0;
	// @(posedge clk_in)		
	// begin
		// mod <= 8'h00;
		// error <= 2'b00;
	// end
	// pc_ins.pc_testbegin;
	// ->start_recv;
	// @(recv_over);
	// release manc0;
	// release manc1;
	// release manc2;
	// release manc3;
	// release manc4;
	// release manc5;
	// release manc6; 
	// release manc7;

	/****************************************10*/
	pc_ins.pc_testbegin;
	$display("[Note:] @%t 10th 128bits random error mode testcase is start ", $time);
	@(posedge clk_in)
	err_ch128 = {$random} % 256;
	if(err_ch128[7])
		force manc7 = 0;
	if(err_ch128[6])
		force manc6 = 0;
	if(err_ch128[5])
		force manc5 = 0;
	if(err_ch128[4])
		force manc4 = 0;
	if(err_ch128[3])
		force manc3 = 0;
	if(err_ch128[2])
		force manc2 = 0;
	if(err_ch128[1])
		force manc1 = 0;
	if(err_ch128[0])
		force manc0 = 0;
	@(posedge clk_in)		
	begin
		mod <= 8'hff;
		error <= 2'b00;
	end
	->start_recv;
	@(recv_over);
	release manc0;
	release manc1;
	release manc2;
	release manc3;
	release manc4;
	release manc5;
	release manc6; 
	release manc7;
	// /**************************************************11**/
	pc_ins.pc_testbegin;
	$display("[Note:] @%t 11th 64bits and 128bit both testcase", $time);
	@(posedge clk_in)
	begin
		mod <= 8'b01010101;
		error <= 2'b00;
	end
	->start_recv;
	@(recv_over);
	
	repeat(100) @(posedge clk_in);
	$finish;	
end


/******************monitor**********************************/
initial
begin: mon
		fork: main_mon
			begin
			// /*************************************1*********/
				@(start_recv);
				pc_ins.recv_jude;
				check_once(0);	
				$display("[Note:] @%t 64bits mode testcase is done ", $time);
				->recv_over;
			/*************************************2********/
				// @(start_recv);
				// pc_ins.recv_jude;
				// check_once(8'hff);
				// $display("[Note:] @%t 64bits trans error mode testcase is done ", $time);
				// ->recv_over;
			// /**************************************3******/
				// @(start_recv);
				// pc_ins.recv_jude;
				// check_once(8'hff);
				// $display("[Note:] @%t 64bits data error mode testcase is done ", $time);
				// ->recv_over;
				
			/************************************4******/
				@(start_recv);
				pc_ins.recv_jude;
				check_once(0);
				$display("[Note:] @%t 128bits mode testcase is done ", $time);
				->recv_over;
				
			/********************************* ****5******/	
				@(start_recv);
				pc_ins.recv_jude;
				check_once(8'hff);
				$display("[Note:] @%t 128bits trans error mode testcase is done ", $time);
				->recv_over;
					
			/***************************************6*********/	
				@(start_recv);
				pc_ins.recv_jude;
				check_once(8'hff);
				$display("[Note:] @%t 128bits data error mode testcase is done ", $time);
				->recv_over;	
			
			// /*************************************7***********/
				// @(start_recv);
				// pc_ins.recv_jude;
				// check_once(0);
				// $display("[Note:] @%t 64bits middle in field testcase is done", $time);
				// ->recv_over;	
		
			/*************************************8***********/
				@(start_recv);
				pc_ins.recv_jude;
				check_once(0);
				$display("[Note:] @%t 128bits middle in field testcase is done", $time);
				->recv_over;
								 
			// /*********************************9***********/	
				// @(start_recv);
				// pc_ins.recv_jude;
				// check_once(err_ch64);
				// $display("[Note:] @%t 64bits random error middle in field testcase is done", $time);	
				// ->recv_over;	
			
			
			/**********************************10**********/	
				@(start_recv);
				pc_ins.recv_jude;
				check_once(err_ch128);
				$display("[Note:] @%t 128bits random error middle in field testcase is done", $time);	
				->recv_over;	
			
			 /********************************11***********/	
			 @(start_recv);
			 pc_ins.recv_jude;
			 check_once(0);
			 $display("[Note:] @%t 64bit and 128bits both testcase is done", $time);
			 ->recv_over;
			 
				disable main_mon;
			end
			begin
				$display("[NOTE:] IN wait_time_out process");
				repeat(10000)@(posedge clk_125k);
				$display("[NOTE:] 1th 10000 clk_125k has gone");
				repeat(10000)@(posedge clk_125k);
				$display("[NOTE:] 2th 10000 clk_125k has gone");
				repeat(10000)@(posedge clk_125k);
				$display("[NOTE:] 3th 10000 clk_125k has gone");
				repeat(10000)@(posedge clk_125k);
				$display("[NOTE:] 4th 10000 clk_125k has gone");
				repeat(10000)@(posedge clk_125k);
				$display("[NOTE:] 5th 10000 clk_125k has gone");
				repeat(10000)@(posedge clk_125k);
				$display("[NOTE:] 6th 10000 clk_125k has gone");
				repeat(10000)@(posedge clk_125k);
				$display("[NOTE:] 7th 10000 clk_125k has gone");
				repeat(10000)@(posedge clk_125k);
				$display("[NOTE:] 8th 10000 clk_125k has gone");
				repeat(10000)@(posedge clk_125k);
				$display("[NOTE:] 9th 10000 clk_125k has gone");
				repeat(10000)@(posedge clk_125k);
				$display("[NOTE:] 10th 10000 clk_125k has gone");
					repeat(10000)@(posedge clk_125k);
				$display("[NOTE:] 11th 10000 clk_125k has gone");
					repeat(10000)@(posedge clk_125k);
				$display("[NOTE:] 12th 10000 clk_125k has gone");
					repeat(100000)@(posedge clk_125k);
				$display("[NOTE:] 13th 100000 clk_125k has gone");
					repeat(100000)@(posedge clk_125k);
				$display("[NOTE:] 14th 100000clk_125k has gone");
					repeat(100000)@(posedge clk_125k);
				$display("[NOTE:] 15th 100000 clk_125k has gone");
				$display("[ERROR:] @%t, no data recevied", $time);
				disable main_mon;
			end
		join
end






/**********************dump**************************/
initial
begin
	$wlfdumpvars();
end


/**********************dump**************************/
initial
begin
	$fsdbDumpfile("sim.fsdb");
	$fsdbDumpvars;
end
		
		
endmodule
							
